import re
import traceback
import logging
logging.basicConfig(level=logging.CRITICAL)

re_var = re.compile(r"^([a-zA-Z_][a-zA-Z0-9]*)[\s]*=(.*)$")

token_val=dict()
def replace(s):
    r = re.split(r'([()| \t]+)',s)
    rep=[token_val[x] if x in token_val else x for x in r]
    return ''.join(rep)

def emptyline(line0):
    line1=line0.replace('\t',' ').strip('\n')
    line2=line1.strip()
    return line2=="", line1, len(line1)

def parseVar(line):
    line=line.strip()
    res = re_var.match(line)
    if res:
        token_val[res.group(1)]=replace(res.group(2).strip())
        return True
    return

gestures=[]
gesture=None
actions=[]
action =[]
def packAction():
    global action,actions
    if action:#end last action
        actions.append('\n'.join(action))
        action=[]

def packGesture():
    global action,actions,gesture,gestures
    packAction()
    if gesture:#end last gesture
        gestures.append((gesture,actions))
        gesture=None
    actions=[]

# 状态量 0->1->1..
# 0：变量区，允许变量，检测$进入1
# 1：动作区，检测$,"##"进入1
state = 0
def readline(line):
    global state, gestures, gesture, actions, action
    # 判断空，取代'\t'，长度
    isempty, line, linelen = emptyline(line)
    if isempty:
        return True
    flag=line[0]
    if state==0:#变量区
        if flag=='$':
            # 第一个连续手势语句行
            gesture=replace(line[1:].strip())#记录新手势
            state=1
        else:#变量解析
            if not parseVar(line):
                logging.error('ERROR:解析变量出错:'+line)
                print('解析变量出错:'+line)
                return
    
    elif state==1:#动作区
        if flag=='$':#连续手势语句行
            packGesture()
            gesture=replace(line[1:].strip())#记录新手势
        elif linelen>1 and line[0:2]=='##':
            packAction()
            action.append(line)
        elif action:
            action.append(line)
        else:
            logging.error('ERROR:等待动作出错:'+line)
            print('解析动作出错:'+line)
            return
    
    return True

def clear():
    global token_val, state, gestures, gesture, actions, action
    token_val={}
    state=0
    gestures=[]
    gesture =None
    actions =[]
    action  =[]

def readlines(lines):
    i_line=1
    for line in lines:
        #print("line:",line)
        ok = readline(line)
        if not ok:
            logging.error('ERROR:出错行数定位:'+str(i_line))
            print('解析出错行数:'+str(i_line))
            return []
        i_line+=1
    else:
        packGesture()

def readConfig(text='config.ini', is_file=True):
    clear()
    try:
        if is_file:
            with open(text) as f:
                readlines(f.readlines())
        else:
            readlines(text.split('\n'))
    except Exception as e:
        traceback.print_exc()
    return gestures

def testConfigVar():
    global token_val, state, gestures, gesture, actions, action
    clear()
    # 可用符号
    vali_char=['_','0','@',' ','=','\n']#,'$'
    # 排列组合
    def enum(n=5):
        if n==0:
            yield ''
            return None
        for c in vali_char:
            if c!='\n':
                for e in enum(n-1):
                    # print(e)
                    yield c+e
            else:
                yield ''
                return None
    # 遍历所有排列，保存正确表达式
    right=[]
    for in_str in enum(7):
        clear()
        ret = readline(in_str)
        if ret:
            res="{:<10} {:<1} {} {} {} {} {}\n".format(in_str, state, token_val, gestures, gesture, actions, action)
            # res="{:<10} {:<1}\n".format(in_str, state)
            print(res)
            right.append(res)
    with open("testConfigVar.txt","w") as f:
        f.writelines(right)

def testConfigGesture():
    global token_val, state, gestures, gesture, actions, action
    clear()
    token_val['token']='val'
    # 可用符号
    vali_char=['_','$',' ','token','\n']#,'$'
    # 排列组合
    def enum(n=5):
        if n==0:
            yield ''
            return None
        for c in vali_char:
            if c!='\n':
                for e in enum(n-1):
                    # print(e)
                    yield c+e
            else:
                yield ''
                return None
    # 遍历所有排列，保存正确表达式
    right0=[]
    right1=[]
    for in_str in enum(7):
        clear()
        token_val['token']='val'
        ret = readline(in_str)
        if ret:
            res="{:<10} {:<1} {} {} {} {} {}\n".format(in_str, state, token_val, gestures, gesture, actions, action)
            # res="{:<10} {:<1}\n".format(in_str, state)
            print(res)
            right0.append(res)
        clear()
        state=1
        token_val['token']='val'
        ret = readline(in_str)
        if ret:
            res="{:<10} {:<1} {} {} {} {} {}\n".format(in_str, state, token_val, gestures, gesture, actions, action)
            # res="{:<10} {:<1}\n".format(in_str, state)
            print(res)
            right1.append(res)
    with open("testConfigGesture0.txt","w") as f:
        f.writelines(right0)
    with open("testConfigGesture1.txt","w") as f:
        f.writelines(right1)

def testConfigReplace():
    global token_val, state, gestures, gesture, actions, action
    clear()
    # 可用符号
    vali_char=['(',')','|',' ','\t','t','\n']#,'$'
    # 排列组合
    def enum(n=5):
        if n==0:
            yield ''
            return None
        for c in vali_char:
            if c!='\n':
                for e in enum(n-1):
                    # print(e)
                    yield c+e
            else:
                yield ''
                return None
    # 遍历所有排列，保存正确表达式
    right=[]
    for in_str in enum(6):
        clear()
        token_val['t']='v'
        ret = replace(in_str)
        if ret:
            res="{:<10} {}\n".format(in_str, ret)
            print(res)
            right.append(res)
    with open("testConfigReplace.txt","w") as f:
        f.writelines(right)

def testConfigTotal():
    global token_val, state, gestures, gesture, actions, action
    clear()
    # 可用符号
    vali_char=[' t = v \n','$ gesture \n','## action \n','   \t \n','\n']#,'$'
    # 排列组合
    def enum(n=5):
        if n==0:
            yield []
            return None
        for c in vali_char:
            if c!='\n':
                for e in enum(n-1):
                    # print(e)
                    yield [c]+e
            else:
                yield []
                return None
    # 遍历所有排列，保存正确表达式
    right=[]
    for in_strs in enum(6):
        clear()
        for in_str in in_strs:
            ret = readline(in_str)
            if not ret:
                break
        else:
            res="{:<100} {:<1} {} {} {} {} {}\n".format(str(in_strs), state, token_val, gestures, gesture, actions, action)
            print(res)
            right.append(res)
    with open("testConfigTotal.txt","w") as f:
        f.writelines(right)

if __name__ == '__main__':
    print(readConfig("0"))
    # testConfigVar()
    # testConfigGesture()
    # testConfigReplace()
    # testConfigTotal()
